package com.ossjk.config.shiro;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.logging.log4j.core.Core;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.ThreadContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.ossjk.core.util.JwtTokenUtil;
import com.ossjk.qlh.system.service.IDepartmentService;
import com.ossjk.qlh.system.service.IPermissionService;
import com.ossjk.qlh.system.service.IRoleService;
import com.ossjk.qlh.system.service.ITokenService;
import com.ossjk.qlh.system.service.IUserService;

/**
 * ShiroConfig:shiro 配置类,配置哪些拦截,哪些不拦截,哪些授权等等各种配置都在这里
 *
 * 很多都是老套路,按照这个套路配置就行了
 *
 * @author zhangxiaoxiang
 * @date: 2019/07/12
 */

@Configuration
public class ShiroConfig {

	@Autowired
	private MyRealm myRealm;

	@Autowired
	private JwtTokenUtil jwtTokenUtil;
	@Autowired
	private IUserService iUserService;
	@Autowired
	private ITokenService iTokenService;
	@Autowired
	private IPermissionService iPermissionService;
	@Autowired
	private IRoleService iRoleService;
	@Autowired
	private IDepartmentService iDepartmentService;

	/**
	 * 注入安全过滤器
	 *
	 * @param securityManager
	 * @return
	 */
	@Bean("shiroFilter")
	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		// 拦截器
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();

		// 添加自己的过滤器并且取名为jwt
		Map<String, Filter> filterMap = new HashMap<String, Filter>(2);
		// 跨域拦截器
		filterMap.put("cros", new CrosFilter());
		// token 拦截器
		filterMap.put("jwt", new JwtFilter(jwtTokenUtil, iUserService, iTokenService, iPermissionService, iRoleService, iDepartmentService));
		shiroFilterFactoryBean.setFilters(filterMap);
		// <!-- 过滤链定义，从上向下顺序执行，一般将/**放在最为下边
		filterChainDefinitionMap.put("/upload/**", "cros,anon");
		filterChainDefinitionMap.put("/login", "cros,anon");
		filterChainDefinitionMap.put("/sendEmail", "cros,anon");
		filterChainDefinitionMap.put("/findPwd", "cros,anon");
		filterChainDefinitionMap.put("/main/getCpuAndMemory", "cros,anon");
		filterChainDefinitionMap.put("/getSystemsetting", "cros,anon");
		// 放行druid监控
		filterChainDefinitionMap.put("/druid/**", "cros,anon");
		// 放行knife4j
		filterChainDefinitionMap.put("/swagger-resources", "cros,anon");
		filterChainDefinitionMap.put("/v2/api-docs", "cros,anon");
		filterChainDefinitionMap.put("/v2/api-docs-ext", "cros,anon");
		filterChainDefinitionMap.put("/doc.html", "cros,anon");
		filterChainDefinitionMap.put("/webjars/**", "cros,anon");

		filterChainDefinitionMap.put("/**", "cros,jwt");
//		filterChainDefinitionMap.put("/**", "cros,anon");

		// 未授权界面;
		shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}

	/**
	 * 注入安全管理器
	 *
	 * @param myRealm
	 * @return
	 */
	@Bean("securityManager")
	public SecurityManager securityManager(MyRealm myRealm) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myRealm);
		/*
		 * 关闭shiro自带的session，详情见文档
		 * http://shiro.apache.org/session-management.html#SessionManagement-
		 * StatelessApplications%28Sessionless%29
		 */
		DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
		DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
		defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
		subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
		securityManager.setSubjectDAO(subjectDAO);
		return securityManager;

	}

	/**
	 * 使用Aop
	 *
	 * @return
	 */
	@Bean
	public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return advisorAutoProxyCreator;
	}

	/**
	 * 生效注解
	 *
	 * @param securityManager
	 * @return
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

}
